﻿using System;
using System.Linq;
using COFE.Core;
using COFE.Core.Lister;
using COFE.Core.Profile;
using NUnit.Framework;
using COFE.Core.Entry;

namespace COFE.Data
{
    /// <summary>
    /// Enable cache the primary property provider only.
    /// </summary>
    public class DBCachePropertyProvider : DBPropertyProviderBase, IPropertyProviderCache
    {
        #region Constructor

        private void init()
        {
            _getProperty = (p) => checkOrgPP().GetProperty(p).Value;
            _setProperty = (p, v) => checkOrgPP().SetProperty(p, v);

        }

        public DBCachePropertyProvider(Entry dbEntry)
            : base(dbEntry)
        {
            init();
        }

        /// <summary>
        /// Assumed the dbEntry already exists.
        /// </summary>
        /// <param name="entryGuid"></param>
        public DBCachePropertyProvider(Guid entryGuid)
            : base(entryGuid)
        {
            init();
        }



        #endregion

        #region Data

        //PrimaryPropertyProvider, use checkOrgPP() instead, which create it if not available.
        IPropertyProvider _cachingPropertyProvider = null;


        #endregion

        #region Public Methods



        #endregion

        #region private methods



        /// <summary>
        /// Check if the original property provider (_cachingPropertyProvider) is created, otherwise create one.
        /// </summary>
        /// <returns></returns>
        private IPropertyProvider checkOrgPP()
        {
            if (_cachingPropertyProvider == null)
            {                       
                IInternalFileSystemInfoExA entry =
                    COFEShared.CurrentUserProfile.TryParsePath(_fullParsePath,
                    EntryConstructionFlags.DefaultWithoutCache | EntryConstructionFlags.LookupIfParseFailed) as IInternalFileSystemInfoExA;
                //if (entry != null && entry.IsPropertySupported(DirectoryInfoProperties.FileBasedFSFile))
                //    entry = entry.GetProperty(DirectoryInfoProperties.FileBasedFSFile).Value as IInternalFileSystemInfoExA;

                // TryParseGuid(_entryGuid, EntryConstructionFlags.DefaultWithoutCache) as IInternalFileSystemInfoExA;
                //Assert.IsNotNull(entries, "Key not found - " + _dbEntry.EntryId.ToString());
                if (entry == null)
                    throw new System.IO.FileNotFoundException(_fullParsePath);                
                Assert.IsNotInstanceOf<DBCachePropertyProvider>(entry.PrimaryPropertyProvider);
                _cachingPropertyProvider = entry.PrimaryPropertyProvider;
            }

            return _cachingPropertyProvider;
        }

        #endregion


        #region Static Method

        public static bool EntryInDatabase(Guid entryGuid)
        {
            return COFEDBShared.DBOperations.ReadDatabase((context) =>
                context.Entries.Any(e => e.EntryId == entryGuid));
        }

        //use COFEDBShared.DBEntryManager.RemoveEntry(_dbEntryId); instead.
        //public static void DeleteEntryInDatabase(Guid entryGuid)
        //{        
        //    COFEDBShared.DBOperations.UpdateDatabase((context) =>
        //    {
        //        var entryToDelete = context.Entries.FirstOrDefault(e => e.EntryId == entryGuid);
        //        if (entryToDelete != null)
        //        {
        //            context.Entries.DeleteObject(entryToDelete);
        //            context.SaveChanges();
        //        }
        //    });
        //}

        #endregion

        #region Public Properties

        public IPropertyProvider CachingPropertyProvider { get { return checkOrgPP(); } }

        #endregion

    }
}
